﻿/*
 * @Author: sonss
 * @Date: 2024-08-17 22:26:22
 * @LastEditTime: 2024-08-29 14:43:25
 * @FilePath: /ss-file-antd/src/requestErrorConfig.ts
 * @Description:
 */
import type { RequestOptions } from '@@/plugin-request/request';
import { history, type RequestConfig } from '@umijs/max';
import { message } from 'antd';
import md5 from 'md5';
import uniqid from 'uniqid';
import { getStorage } from './utils/storage';

// 与后端约定的响应数据格式
interface ResponseStructure {
  code: number;
  data: any;
  message?: string;
}

/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res: ResponseStructure) => {
      if (res.code !== 0) {
        const error: any = new Error(res.message || '未知错误');
        error.name = 'BizError';
        error.info = res;
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const info: ResponseStructure | undefined = error.info;
        if (info) {
          message.error(info.message || '未知错误');
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(`Response status:${error.response.status}`);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      const url = window.configs ? window.configs?.api.uri + config.url : config.url;
      const headers: any = config.headers || {};
      headers['Content-Type'] = 'application/json;charset=utf-8';
      const identity = getStorage('identity');
      if (identity) {
        headers['stuffid'] = identity.stuffId + '';
        headers['acctype'] = identity.accountType + '';
        headers['nonce'] = uniqid();
        headers['timestamp'] = new Date().getTime() + '';
        headers['sign'] = md5(
          headers['stuffid'] +
            headers['acctype'] +
            headers['nonce'] +
            headers['timestamp'] +
            identity.accessToken,
        );
      }

      return { ...config, url, headers };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      // 拦截响应数据，进行个性化处理
      const { data } = response as unknown as ResponseStructure;
      if (data?.code !== 0) {
        message.error(data.message || '请求失败！');
        if (data.code === 401) {
          history.push('/user/login');
        }
      }
      return response;
    },
  ],
};
